home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Over 1,000 Windows 95 Programs
/
Over 1000 Windows 95 Programs (Microforum) (Disc 1).iso
/
1138
/
source.zip
/
THREAD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-06
|
5KB
|
233 lines
/* thread.c -- Threads messages for easier perusal
This file is part of Paperboy, an offline mail/newsreader for Windows
Copyright (C) 1995 Michael H. Vartanian
vart@clark.net
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "error.h"
#include "soup.h"
#include "structs.h"
#include "msgs.h"
#include "areas.h"
#include "thread.h"
struct llmsg ** hold;
char * stripsubject (char * subject)
{
/* Remove leading RE: to get down to a basic subject */
char * stripped;
int replen; /* Cache length for performance (loop invariant)*/
assert(subject!=NULL);
stripped=subject;
replen=strlen(REPLYSTR);
while (_fstrnicmp(stripped,REPLYSTR,replen)==0)
{
stripped+=replen;
}
return stripped;
}
static int comparemsg (const void * m1, const void * m2)
{
struct llmsg * msg1, * msg2;
struct llmsg ** p;
time_t comp;
p=NULL;
msg1=NULL;
msg2=NULL;
assert(m1!=NULL);
assert(m2!=NULL);
if (m1==m2) return 0;
p=(struct llmsg **)m1;
msg1=(struct llmsg *)*p;
p=(struct llmsg **)m2;
msg2=(struct llmsg *)*p;
/* I've had loads of trouble debugging this routine, can't you tell ? */
assert(msg1!=NULL);
assert(msg2!=NULL);
if (msg1==msg2) return 0;
assert(msg1->magic==MSGMAGIC);
assert(msg2->magic==MSGMAGIC);
comp=msg1->thread_idate - msg2->thread_idate;
if (comp==0) /* Same thread, sort by date */
{
/* Always put base of thread first, regardless of date
(our date routine farkles timezones) */
assert(msg1->subject!=NULL);
assert(msg2->subject!=NULL);
if (stripsubject(msg1->subject)==msg1->subject) return -1;
if (stripsubject(msg2->subject)==msg2->subject) return 1;
comp=msg1->idate - msg2->idate;
}
if (comp>0) return 1;
if (comp<0) return -1;
return 0;
}
void ComputeBaseThreadDate(struct llareas * area)
{
/* For every message in this group, find the date of it's earliest
thread.
We're not terribly efficient in this routine O(n^2), but it works.
*/
struct llmsg * cur, * inner;
char * subj1, * subj2;
assert(area!=NULL);
cur=area->head;
while (cur)
{
subj1=stripsubject(cur->subject);
inner=area->head;
while (inner)
{
subj2=stripsubject(inner->subject);
if (!strnicmp(subj1,subj2,SIGTHREAD)) /* Base subjects are the same */
{
if (inner->idate < cur->thread_idate)
cur->thread_idate=inner->idate;
}
inner=inner->next;
}
cur=cur->next;
}
}
int DLLFUNC ThreadMsgs (int index)
{
struct llareas * area;
struct llmsg * msghead;
int nummsg;
int pt;
assert(index>0);
assert(index<=GetNumAreas());
area=findarea(index);
assert(area!=NULL);
ComputeBaseThreadDate(area);
nummsg=GetNumMsgs(index);
assert(nummsg!=0);
/* We create an array large enough to hold pointers to all messages */
hold=(struct llmsg **)malloc(sizeof(struct llmsg *) * nummsg);
if (hold==NULL) { errortext="ThreadMsgs: pointer array"; return ERRMEM; }
memset(hold, 0, sizeof(struct llmsg *) * nummsg );
/* Now stuff pointers to each element into the array */
msghead=area->head;
assert(msghead!=NULL);
for (pt=0; pt<nummsg; pt++)
{
assert(msghead!=NULL);
assert(msghead->magic==MSGMAGIC);
hold[pt]=msghead;
msghead=msghead->next;
}
assert(pt==nummsg);
/* Sort the array */
qsort(hold, nummsg, sizeof(struct llmsg *), comparemsg);
/* Reassemble the linked list */
area->head=hold[0];
for (pt=0; pt<nummsg-1; pt++)
hold[pt]->next=hold[pt+1];
hold[pt]->next=NULL; /* End of list */
free(hold);
return 0;
}
void reverseorder (struct llareas * area)
{
struct llmsg * msghead;
struct llmsg * cur;
int nummsg;
int pt;
assert (area!=NULL);
cur=area->head;
nummsg=0;
while (cur!=NULL)
{
cur=cur->next;
nummsg++;
}
if (nummsg==0) return;
assert(nummsg!=0);
/* We create an array large enough to hold pointers to all messages */
hold=(struct llmsg **)malloc(sizeof(struct llmsg *) * nummsg);
if (hold==NULL) { errortext="ThreadMsgs: pointer array"; return; }
memset(hold, 0, sizeof(struct llmsg *) * nummsg );
/* Now stuff pointers to each element into the array */
msghead=area->head;
assert(msghead!=NULL);
/* for (pt=0; pt<nummsg; pt++) */
for (pt=nummsg-1; pt>=0; pt--)
{
assert(msghead!=NULL);
assert(msghead->magic==MSGMAGIC);
hold[pt]=msghead;
msghead=msghead->next;
}
/* Reassemble the linked list */
area->head=hold[0];
for (pt=0; pt<nummsg-1; pt++)
hold[pt]->next=hold[pt+1];
hold[pt]->next=NULL; /* End of list */
free(hold);
}